/*******************************************************************************************************
 nomacs is a fast and small image viewer with the capability of synchronizing multiple instances
 
 Copyright (C) 2011-2016 Markus Diem <markus@nomacs.org>
 Copyright (C) 2011-2016 Stefan Fiel <stefan@nomacs.org>
 Copyright (C) 2011-2016 Florian Kleber <florian@nomacs.org>

 This file is part of nomacs.

 nomacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 nomacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

 related links:
 [1] https://nomacs.org/
 [2] https://github.com/nomacs/
 [3] http://download.nomacs.org
 *******************************************************************************************************/

#pragma once

#pragma warning(push, 0)	// no warnings from includes
#include <QAction>
#include <QSettings>
#pragma warning(pop)

#pragma warning(disable: 4251)	// TODO: remove

#ifndef DllCoreExport
#ifdef DK_CORE_DLL_EXPORT
#define DllCoreExport Q_DECL_EXPORT
#elif DK_DLL_IMPORT
#define DllCoreExport Q_DECL_IMPORT
#else
#define DllCoreExport Q_DECL_IMPORT
#endif
#endif

// Qt defines

namespace nmc {

// nomacs defines
class DkImageContainer;

/// <summary>
/// Base class of simple image manipulators.
/// Manipulators are functions that map
/// an image to an image (e.g. grayscale).
/// If this class is extended, batch processing
/// can make use of it too.
/// </summary>
class DllCoreExport DkBaseManipulator {

public:
	DkBaseManipulator(QAction* action = 0);

	QString name() const;
	QAction* action() const;
	QIcon icon() const;

	void setSelected(bool select);
	bool isSelected() const;

	virtual QString errorMessage() const = 0;
	virtual QImage apply(const QImage& img) const = 0;

	virtual void saveSettings(QSettings& settings);
	virtual void loadSettings(QSettings& settings);

private:
	QAction* mAction = 0;
	bool mIsSelected = false;
};

/// <summary>
/// Extended image manipulators.
/// These manipulators have settings
/// and a UI that allows users to manipulate
/// the settings.
/// </summary>
/// <seealso cref="DkBaseManipulator" />
class DllCoreExport DkBaseManipulatorExt : public DkBaseManipulator {

public:
	DkBaseManipulatorExt(QAction* action);

	void setWidget(QWidget* widget);
	QWidget* widget() const;

	void setDirty(bool dirty);
	bool isDirty() const;

private:
	bool mDirty = false;
	QWidget* mWidget = 0;
};

class DllCoreExport DkManipulatorManager {

public:
	DkManipulatorManager();

	// simple manipulators
	enum ManipulatorId {
		m_grayscale = 0,
		m_auto_adjust,
		m_normalize,
		m_invert,
		m_flip_h,
		m_flip_v,

		m_end
	};

	// extended manipulators
	enum ManipulatorExtId {
		m_rotate = m_end,
		m_resize,
		m_threshold,
		m_color,
		m_hue,
		m_exposure, 
		m_tiny_planet,
		m_blur,
		m_unsharp_mask,
		
		m_ext_end
	};

	void createManipulators(QWidget* parent);

	QVector<QAction*> actions() const;
	QStringList names() const;
	
	QSharedPointer<DkBaseManipulatorExt> manipulatorExt(const ManipulatorExtId& mId) const;
	QSharedPointer<DkBaseManipulator> manipulator(const ManipulatorId& mId) const;
	QSharedPointer<DkBaseManipulator> manipulator(const QAction* action) const;
	QSharedPointer<DkBaseManipulator> manipulator(const QString& name) const;
	QVector<QSharedPointer<DkBaseManipulator> > manipulators() const;

	int numSelected() const;

	void loadSettings(QSettings & settings);
	void saveSettings(QSettings & settings) const;

private:
	QVector<QSharedPointer<DkBaseManipulator> > mManipulators;
};
}